经典面试题之for 循环和闭包 您所在的位置:网站首页 JavaScript For 循环 经典面试题之for 循环和闭包

经典面试题之for 循环和闭包

2024-01-15 00:58| 来源: 网络整理| 查看: 265

前言

最近又温故而知新了一遍JavaScript的闭包,前面几年懵懵懂懂看了很多篇文章,今天再看还是受益匪浅,从而也搞懂了一道经典面试题,这个面试题之前也迟迟不理解,直到今天才豁然开朗。接下来就来逐步分析分析这道经典面试题。

题目 1: var data = []; 2: for (var i = 0; i < 3; i++) { 3: data[i] = function () { 4: console.log(i); 5: }; 6: } 7: 8: data[0](); // 3 9: data[1](); // 3 10:data[2](); // 3 分析:

开始 JavaScript执行的是全局上下文作用域。

第一行声明的全局变量 data,并赋值为一个空数组

2-6行 定义了一个for 循环体,此时重点就在这个循环体里面了,再细细拆分来看。

循环体中 var i = 0; 声明的也是全局变量,i < 3; i++ 是循环条件。

循环体里面 变量data 开始进行被赋值,而且是经过了三次赋值,其结果拆开来写就是:

data[0] = function(){ console.log(i) } data[1] = function(){ console.log(i) } data[2] = function(){ console.log(i) }

此时注意 三次循环赋值 的结果的函数体内都是 console.log(i) ,而并不是console.log(0),console.log(1),console.log(2),此时的三个函数都是声明中,并未开始调用执行;

真正执行函数是 8 - 9 行,单独拿出每个数组中的函数执行。

再结合 全局声明的var i = 0; 经过三次循环,全局的 i 等于 3 了。

最后 调用函数体内的 console.log(i),此时的 i 找到的就是 全局变量 i = 3,最后输出执行的都是 console.log(3) 这个结果。

分析原因

为什么会造成这样的结果。在没了解到闭包之前,还傻傻的以为输出的是 0,1,2,但因为词法作用域的原因,导致了这样的结果,因为污染了全局变量,导致函数作用域一层一层往上找的过程,没有找到对应点变量,就找了全局的变量。

解决方案

相信网上也有很多这类面试题的解法,我也不过多描述,主要氛围异步setTimeOut处理,和ES6 let声明处理。

setTimeOut 自执行函数和闭包 var data = []; for (var i = 0; i < 3; i++) { (function(i){ setTimeout(data[i] = function () { console.log(i); }, 0) })(i) } data[0](); data[1](); data[2](); 用 let var data = []; for (let i = 0; i < 3; i++) { data[i] = function () { console.log(i); } } data[0](); data[1](); data[2](); 最后

经过这次理解函数的闭包,再结合这道经典面试题,让我更深刻的理解了一遍闭包中的全局作用域 和 词法作用域。突然发现好多原理性的东西都是需要多看几遍才能深刻理解,每次看都有或多或少的收货。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有